﻿using BookSleeve;
using Castle.Core.Configuration;
using Inovout.Application;
using Inovout.YunYao.Live.Web.Models;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace Inovout.YunYao.Live.Web.Controllers
{
    public class NodeController : AsyncController
    {
        protected long UtcNowTimestamp
        {
            get { return Decimal.ToInt64(Decimal.Divide(DateTime.Now.Ticks - 621355968000000000, 10000)); }
        }
        public Task<ActionResult> Index(long node, int interval, long? timestamp)
        {
            return Task.Factory.StartNew<List<MonitorData>>(() =>
                {
                    AsyncManager.Parameters.Add("start", DateTime.Now.Ticks);
                    List<MonitorData> list = GetFromRedis(node,
                        timestamp.HasValue ? timestamp.Value : UtcNowTimestamp - 1000 * 3600 * 24 * 12);
                    return list;
                }).ContinueWith<ActionResult>(task =>
                   {
                       TimeSpan timeInterval = new TimeSpan(DateTime.Now.Ticks - (long)AsyncManager.Parameters["start"]);
                       if (timeInterval.Milliseconds < interval * 1000)
                       {
                           Thread.Sleep(interval * 1000 - timeInterval.Milliseconds);
                       }
                       return Json(task.Result, JsonRequestBehavior.AllowGet);
                   });
        }
        private List<MonitorData> GetFromRedis(long node, long timestamp)
        {
            List<MonitorData> list = new List<MonitorData>();
            IApplication application = ComponentRegistry.Resolve<IApplication>();
            IConfiguration redisConfiguration = application.Configuration.Children["redis"];
            using (var redisConnection
                = new RedisConnection(redisConfiguration.Attributes["ip"], int.Parse(redisConfiguration.Attributes["port"].Trim())))
            {
                redisConnection.Open();
                int dbid = int.Parse(redisConfiguration.Attributes["dbid"].Trim());
                Task<KeyValuePair<string, double>[]> task
                    = redisConnection.SortedSets.RangeString(dbid,
                    "rt_" + node.ToString(), (double)timestamp, minInclusive: false, queueJump: true);
                foreach (var kv in task.Result)
                {
                    MonitorData data = new MonitorData();
                    data.timestamp = (long)kv.Value;
                    foreach (var item in kv.Key.Split('&'))
                    {
                        string[] kvItem = item.Split('=');
                        switch (kvItem[0])
                        {
                            case "v":
                                data.value = int.Parse(kvItem[1]);
                                break;
                        }
                    }
                    list.Add(data);
                }
            }
            return list;
        }
    }
}
